//teh redender method here is not async for easy to test
describe('tempHelper ', function() {
    var t1, t2, div1, div2, data1, data2, fn1, container, fn2, div3, fn3, d1, d2, d3;

    var t4, div4, d4, fn4, data3;
    beforeEach(function() {
        div1 = setFixtures("<div id='div1'></div>")
        div2 = setFixtures("<div id='div2'></div>")
        div3 = setFixtures("<div id='div3'></div>")
        div4 = setFixtures("<div id='div4'></div>")
        $.ajax = mocka.mockView()
        jasmine.clock().install()

        data1 = {
            str: "value",
            num: 3,
            arr: ["v1", "v2"]
        }
        data2 = {
            str1: "value",
            num1: 3,
            arr1: ["v1", "v2"]
        }

        data3 = {
            elems: [1, 2, 3]
        }
        fn1 = function() {}
        fn2 = function() {}
        fn3 = function() {}
        fn4 = function() {}
        container = {
            fn1: fn1,
            fn2: fn2,
            fn3: fn3,
            fn4: fn4
        }
        spyOn(container, "fn1")
        spyOn(container, "fn2")
        spyOn(container, "fn3")
        spyOn(container, "fn4")

        render(data1, "tempHelperSpec_1", div1, function() {
            container.fn1()
            t1 = jc.th(div1)
            d1 = t1.data()
        })

        render(jc.mix(true, {}, data1), "tempHelperSpec_1", div2, function() {
            container.fn2()
            t2 = jc.th(div2)
            d2 = t2.data()
        })
        render(data2, "tempHelperSpec_1", div3, function() {
            container.fn3()
            t3 = jc.th(div3)
            d3 = t3.data()
        })

        jc.render(jc.mix(true, {}, data1), "tempHelperSpec_2", div4, function() {
            container.fn4()
            t4 = jc.th(div4)
            d4 = t4.data()
        })
    })
    afterEach(function() {
        jasmine.clock().uninstall();
        session = {}; //清空掉session
    })
    describe("getCleanData", function() {
        it("can get the data without $index and $path", function() {
            var arr = [{
                    $index: 0,
                    $path: "path",
                    value: "v"
                }, {
                    $index: 1,
                    $path: "path1",
                    value: "value"
                }],
                cleanArr = [{
                    value: "v"
                }, {
                    value: "value"
                }];

            var renderData = {
                    str: "str",
                    num: 321,
                    bol: true,
                    arr: [1, 3, 4, 5],
                    emptyArr: [],
                    obj: {
                        str: "str",
                        arr: arr
                    },
                    otherArr: arr
                },
                cleanData = {};

            tempHelperObj.getCleanData(cleanData, renderData)
            renderData.obj.arr = cleanArr
            renderData.otherArr = cleanArr
            expect(cleanData).toEqual(renderData)
        })
    })
    describe("render", function() {
        it("can render the same div again", function() {

            jc.render(jc.mix(true, {}, data1), "tempHelperSpec_2", div4, function() {
                container.fn4()
                t4 = jc.th(div4)
                d4 = t4.data()
            })
        })
    })
    describe('listen ', function() {

        // it('has different data and ids even the input of data is the same one', function() {
        //     expect(t1.data()).not.toBe(t2.data())
        //     expect(t1.data().arr).not.toBe(t2.data().arr)
        //     expect(t1._data("id")).not.toBe(t2._data("id"))
        // })


        it('has the data and different id when the input of data is the same one', function() {
            render(data1, "tempHelperSpec_1", div2, function() {
                container.fn2()
                t2 = jc.th(div2)
                d2 = t2.data()
            })
            expect(t1.data()).toBe(t2.data())
            expect(t1.data().arr).toBe(t2.data().arr)
            expect(t1._data("id")).not.toBe(t2._data("id"))
        })

        it('can spy on an object atrribute', function() {
            t2.listen("str", div1)
            t1.data().str = "change"
            expect(t2.data().str).toBe("change")
        });

        // it("can use set to change an arr value", function() {
        //     // t1.listen("str", div1)
        //     // t1.data().str = "change"
        //     // expect(t1.data().str).toBe("change")
        //     //t1.listen("arr.0", div1)
        //     t1.data().arr.set(0, "change")
        //     expect(t1.data().arr[0]).toBe("change")

        // })
        describe("can spy on array", function() {
            it("when the element is changed by 'set' method ", function() {
                t2.listen("arr.0", div1)
                d1.arr.set(0, "change")
                expect(t2.data().arr[0]).toBe("change")
            })

            it("when the array is changed by evaluated", function() {
                t2.listen("arr.0", div1)
                var arr = [1, 2]
                t1.data().arr = arr
                expect(t2.data().arr).toBe(arr)
            })
            it("when the array is changed by the array method", function() {
                t2.listen("arr", div1)
                t1.data().arr.push(3)
                expect(t1.data().arr).toEqual(["v1", "v2", 3])
                expect(t2.data().arr).toEqual(["v1", "v2", 3])
            })

        })



        it("can spy on the mixture of a object path", function() {
            t2.listen(data1, div1)
            var d1 = t1.data()
            d1.str = "change1"
            d1.num = "change2"
            d1.arr = [1, 2]
            var d2 = t2.data()

            expect(d2.str).toBe("change1")
            expect(d2.num).toBe("change2")
            expect(d2.arr).toEqual([1, 2])

        });

        describe('can specify the target', function() {
            it("when the target is a string", function() {
                t3.listen("str1", div2, "str")
                d2.str = "change"
                expect(t3.data().str1).toBe("change")
            })
            it("when the target is an array", function() {
                var source = ["str1", "num1"]
                var target = ["str", "num"]
                t3.listen(source, div2, target)
                d2.str = "change1"
                d2.num = "change2"
                expect(d3.str1).toBe("change1")
                expect(d3.num1).toBe("change2")
            })
        });
    });

    describe('unbind', function() {
        it("$all can work", function() {
            t2.listen(data1, div1)
            //t2.unbind("$all")
            t1.unbind("$all")
            d1.str = 'abc'
            expect(d2.str).not.toEqual("abc")
        })

    });
    describe('reRender', function() {

        it("can change the template data", function() {
            t4.reRender("uniqueId", {
                str: "abc"
            })
            expect(d4.str).toBe("abc")
        })
        it("not affects the bind", function() {
            t3.listen("str", div4)
            t4.reRender("uniqueId", {
                str: "abc"
            })
            expect(d3.str).toBe("abc")
        })

    });
})